
	Ext.namespace("panel.widgets");
	
	/**
	 * @param {Object} config
	 *
	 * config.unique (true) Bool - Allow unique list?
	 * config.hooks.isItemApplicable(item, uids)
	 * config.store - If Ext.data.Store - Overload existent
	 * config.store.fields []   - Additional fields
	 * config.store.sortInfo [] - Sort Info
	 * config.positioner Bool/{} - Positioner/Positioner config
	 * config.grid {} - Grid config
	**/
	panel.widgets.list = function(config) {
		
		var state  = {};
		var widget = {};
				
		/**
		 * Config 
		**/
		config            = Ext.value(config,            {});
		config.hooks      = Ext.value(config.hooks,      {});
		config.unique     = Ext.value(config.unique,     true);
		config.hierarchy  = Ext.value(config.hierarchy,  false);
		config.selection  = Ext.value(config.selection,  {});
		config.grid       = Ext.value(config.grid,       {});
		config.grid.hooks = Ext.value(config.grid.hooks, {});
		config.grid.columns = Ext.value(config.grid.columns, []);
		config.grid.tbarFit = Ext.value(config.grid.tbarFit, {});
		config.grid.bbarFit = Ext.value(config.grid.bbarFit, {});
		config.positioner = Ext.value(config.positioner, false);
		config.search     = Ext.value(config.search,     {});
		config.editable   = Ext.value(config.editable,   true);
		config.simple     = Ext.value(config.simple,     false);
		config.paginator  = Ext.value(config.paginator,  false);
		
		if( config.selection === true ) {
			config.selection = {}; }
			
		if( config.positioner === true ) {
			config.positioner = {}; }
			
		if( config.paginator === true ) {
			config.paginator = {}; }
		
		config.selection.useCheckboxes = Ext.value(config.selection.useCheckboxes, true);
		config.selection.useSelection  = Ext.value(config.selection.useSelection,  true); 
		config.selection.statusbar     = Ext.value(config.selection.statusbar,     true);
		
		/**
		 * Config: Store
		**/
		config.store  = Ext.value(config.store, {});
		
		if( !(config.store instanceof Ext.data.Store ) ) {
			
			config.store.fields = Ext.value(config.store.fields, []);
			
		}	// if
		
		/**
		 * Widget.ID
		**/
		widget.id = Ext.value(config.id, "PW:list:" + Ext.id());
		
		/**
		 * Texts
		**/
		config.texts               = Ext.value(config.texts, {});
		config.texts.item          = Ext.value(config.texts.item, "item");
		config.texts.items         = Ext.value(config.texts.items, "items");
		config.texts.list_is_empty = Ext.value(config.texts.list_is_empty, "List is empty");
		
		/**
		 * Observer 
		**/
		widget.observer = new Ext.util.Observable();
		
		widget.observer.addEvents({
						
			"test_item_is_applicable" : true,
			"modified"      : true,
			"before_reload" : true,
			"reload"        : true,			
			"init"          : true,
			"destroy"       : true
			
		});
		
		if( config.editable ) {
			
			widget.observer.addEvents({
				
				"before_items_add" : true,
				
				"items_added"   : true,
				"items_removed" : true,
				"items_modified": true
				
			});
			
		}	// if
		
		$H(config.listeners).each( function(f, e) {
			
			widget.observer.on(e, f);
			
		});
		
		/**
		 * Locker
		**/
		widget.locker = new Ext.ux.locker;
		
		/**
		 * Init
		**/
		
		widget.init = function() {
			
			//panel.console.log(widget.id, "INIT");
			
			widget.observer.fireEvent("init", widget, config);
			
		};
		
		widget.destroy = function() {
			
			widget.observer.fireEvent("destroy");
			widget.observer.purgeListeners();
			
		};
		
		widget.observer.on("destroy", function() {
			
			state.cache.uids = undefined;
			state.cache = undefined;
			state = undefined;
			
		});
		
		/**
		 * Cache 
		**/		
		state.cache = {
			
			uids: {}
			
		};
		
		/**
		 * UIDS: 
		**/
		widget.getUIDS = function() {
			
			return state.cache.uids;
			
		};
		
		widget.collectUIDS = function() {
			
			panel.console.log(widget.id, "A", "COLLECT UIDS");
			
			state.cache.uids = {};
			
			widget.store.each( function(record) {
				
				state.cache.uids[record.data.uid] = record.data.uid;
				
			});
			
			return state.cache.uids;
			
		};
		
		/**
		 * Collect UIDs on store changes 
		**/
		widget.observer.on("init", function() {
			
			var _fe = function() { widget.collectUIDS(); };
			
			widget.observer.on("reload", _fe);
			
			if( config.editable ) {
				
				widget.observer.on("items_added",   _fe);
				widget.observer.on("items_removed", _fe);
				
			}	// if
			
		});
		
		/**
		 * API:
		**/
		widget.hasItems = 
		widget.getCount = function() {
			
			return widget.store.getCount();
			
		};
		
		if( config.editable ) {
		
			widget.removeItem = function(item) {
			
				widget.store.remove(item);
			
				panel.console.log(widget.id, "REMOVE ITEM");
				widget.observer.fireEvent("items_removed");
			
				return true;
			
			};
			
			widget.removeItems = function(items) {
			
				widget.store.suspendEvents();
				
				items.each( function(item) {
				
					widget.store.remove(item);
					
				} );
				
				widget.store.resumeEvents();
				
				widget.store.filtersApply();
				
				widget.store.fireEvent("datachanged");
			
				panel.console.log(widget.id, "REMOVE ITEMS", items.length);
				
				widget.observer.fireEvent("items_removed", items);
			
				return true;
			
			};
			
		}	// if

		widget.getItem = function(uid) {
			
			return widget.store.getById(uid);
			
		};
		
		widget.getItems = function() {
			
			return widget.store.getSnapshot();
			
		};
		
		widget.ensureVisible = function(record) {
			
			var n    = widget.store.indexOf(record);
			var cell = Ext.get( widget.grid.getView().getCell( n , 0) );
											
			Ext.get(cell).scrollIntoView( widget.grid.getView().scroller );
			
		};
		
		widget.resetItemsState = function() {
			
			widget.getItems().each( function(r) {
				
				if( !config.simple ) {
					
					r.data.is_new      = false;
					r.data.is_modified = false;
					r.data.is_error    = false;
					
				}	// if
				
				if( config.selection ) {
					r.data.is_checked  = false; }
				
			});
			
			widget.store.getRange().each( function(r) {
				
				if( !config.simple ) {
					
					r.data.is_new      = false;
					r.data.is_modified = false;
					r.data.is_error    = false;
					
				}	// if
				
				if( config.selection ) {
					r.data.is_checked  = false; }
				
			});
			
			widget.store.fireEvent("datachanged");
			
		};
		
		widget.loadData = function(data, options) {
			
			if( !widget.observer.fireEvent("before_reload") ) {
				return; }
				
			options = Ext.value(options, {});
			
			//panel.console.log(widget.id, "A", "LOAD DATA");
			
			data.each( function(r) {
					
				if( !config.simple ) {
					
					r.is_new      = false;
					r.is_modified = false;
					r.is_error    = false;
					
				}	// if
				
				if( config.selection ) {
					r.is_checked  = false; }
				
			});

			if( config.hierarchy ) {
				
				options.applySort = Ext.value(options.applySort, false);

				widget.store.loadData(data, false, options);
			
			} else {
			
				widget.store.loadData(data);
				
			}	// if
			
			widget.observer.fireEvent("reload");

		};
		
		widget.isItemApplicable = function(item, param) {

			var uids = widget.getUIDS();
			
			try {
				
				if( widget.observer.fireEvent("test_item_is_applicable", item, uids) === false ) {
					return false; }
					
			} catch( e ) {
				
				return e;
				
			}	// try
			
			if( param && param.onlyCustom ) {
				return true; }

			if( config.unique && uids[item.data.uid] != undefined ) {
				return "Item is already in list."; }
					
			return true;
			
		};
		
		if( config.editable ) {
		
			widget.addItem = function(item) {

				if( widget.isItemApplicable(item) !== true ) {
					return false; }
					
				var record = {
					
					uid: item.data.uid
					
				};
				
				if( !config.simple ) {
					
					record.is_modified = false;
					record.is_new      = true;
					record.is_error    = false;
					
				};
				
				if( config.selection ) {
					record.is_checked  = false; }
				
				if( config.store.fields ) {
					
					config.store.fields.each( function(field) {
						
						if( field.defaultValue != undefined ) {
							
							record[field.name] = 
								( field.defaultValue instanceof Function ) ? 
									field.defaultValue(item) :
									field.defaultValue
							; 
														
						}	// if
						
					} );
					
				}	// if
				
				var record = new Ext.data.Record(record, item.data.uid);

				widget.store.addSorted(record);
				
				if( widget.store.snapshot ){
            		widget.store.snapshot.addAll([record]); }
				
				panel.console.log(widget.id, "ADDED ITEM");
				
				widget.observer.fireEvent("items_added", [record]);
				
				return true;
				
			};
			
			widget.addItems = function(items) {
				
				items.each( function(item, k) {
				
					if( widget.isItemApplicable(item) !== true ) {
						
						delete items[k]; 
						
					}	// if
					
				});
				
				items.clean();
				
				if( !items.length ) {
					return false; }
					
				var records = [];
					
				items.each( function(item, k) {
					
					var record = {
					
						uid : item.data.uid
						
					};
					
					if( !config.simple ) {
						
						record.is_modified = false;
						record.is_new      = true;
						record.is_error    = false;
						
					};
					
					if( config.selection ) {
						record.is_checked  = false; }
					
					if( config.store.fields ) {

						widget.store.fields.each( function(field) {
							
							if( field.defaultValue != undefined ) {
								
								record[field.name] = 
									( field.defaultValue instanceof Function ) ? 
										field.defaultValue(item) :
										field.defaultValue
								; 
								
							}	// if
							
						} );
						
					}	// if
					
					records.push( new Ext.data.Record(record, item.data.uid) );
					
				});
				
				widget.store.add(records);
				
				panel.console.log(widget.id, "ADDED ITEMS", records.length);
				
				widget.observer.fireEvent("items_added", records);
				
				return true;
				
			};
			
		}	// if
		
		/**
		 * Store:
		**/
		
		if( config.store instanceof Ext.data.Store ) {
			
			widget.store = config.store;
			
		} else {
		
			widget.observer.on("destroy", function() {
			
				widget.store.destroy();
				widget.store = undefined;
				
			});
			
			widget.store = {};
			widget.store.listeners     = Ext.value(config.store.listeners, {});
			widget.store.url           = Ext.value(config.store.url, undefined);
			widget.store.totalProperty = Ext.value(config.store.totalProperty, undefined);
			widget.store.root          = Ext.value(config.store.root, undefined);
			widget.store.autoLoad      = Ext.value(config.store.autoLoad, false);
			
			widget.store.fields = [
				
				{ name: "uid", type: "string", defaultValue: function(r) { return r.data.uid; } }

			];
			
			if( config.selection && config.selection.useCheckboxes ) {
				
				widget.store.fields.push(
					{ name: "is_checked", type: "bool", defaultValue: function(r) { return Ext.value(r.data.is_checked, false); }   }
				); 
				
			}	// if
				
			if( !config.simple ) {
			
				widget.store.fields.push(
					{ name: "is_modified", type: "bool", defaultValue: function(r) { return r.data.is_modified; } },
					{ name: "is_new",      type: "bool", defaultValue: function(r) { return r.data.is_new;      } },
					{ name: "is_error",    type: "bool", defaultValue: function(r) { return r.data.is_error;    } }
				);
				
			};
						
			if( config.hierarchy ) {
				
				widget.store.fields.push(
					{ name: "parent",      type: "auto", defaultValue: function(r) { return r.data.parent; }   },
					{ name: "parents",     type: "auto", defaultValue: function(r) { return r.data.parents; }  },
					{ name: "is_leaf",     type: "bool", defaultValue: function(r) { return r.data.is_leaf; }   }
				);
				
			}	// if
			
			config.store.fields.each( function(field) {
				
				if( field.defaultValue == undefined ) {
					
					field.defaultValue = function(r) { return r.data[field.name]; }
					
				};
				
				widget.store.fields.push(field);
				
			});
			
			if( config.positioner && config.positioner.dataIndex == undefined ) {
				
				widget.store.fields.push({ name: "position", type: "int", defaultValue: function(r) { return r.data.position; } });
				
			}	// if
			
			// Sort Info
			
			switch( true ) {
			
			case config.store.sortInfo != undefined:
				widget.store.sortInfo = config.store.sortInfo;
				break;
				
			case config.positioner !== false:
				
				widget.store.sortInfo = Ext.value(config.store.sortInfo, { 
					
					field: Ext.value(config.positioner.dataIndex, "position"), 
					direction: "ASC" 
					
				});
				
				break;
				
			}	// switch		
			
			if( config.hierarchy ) {
				
				widget.store.parent_id_field_name = "parent";
				widget.store.leaf_field_name      = "is_leaf";
				
				widget.store.reader = new Ext.data.JsonReader({
				
					id            : "uid",
					totalProperty : Ext.value(config.store.totalProperty, undefined),
					root          : Ext.value(config.store.root, undefined),
					fields        : widget.store.fields				
					
				});
				
				widget.store = new Ext.ux.maximgb.treegrid.AdjacencyListStore(widget.store);
				
			} else {
				
				widget.store.id            = "uid";
				widget.store.fields        = widget.store.fields;
				widget.store.totalProperty = Ext.value(config.store.totalProperty, undefined);
				widget.store.root          = Ext.value(config.store.root, undefined);
				
				widget.store = new Ext.data.JsonStore(widget.store);
				
			}	// if
			
			widget.store.on("loadexception", panel.widgets.chunks.stubs.onAjaxFailure);
			
		}	// if
		
		widget.observer.on("init", function() {
			
			var _fe = function() { 
			
				widget.observer.fireEvent("modified");
				 
			};
		
			widget.store.on("add",    _fe);
			widget.store.on("remove", _fe);
			widget.store.on("update", _fe);
			widget.store.on("clear",  _fe);
			widget.store.on("load",   _fe);
			widget.store.on("datachanged", _fe);
			
		});
		
		/**
		 * Selection:
		**/
		if( config.selection ) {
		
			if( config.selection === true ) {
				config.selection = {}; }
		
			widget.selection = {
				
				id             : widget.id + ":selection",
				store          : widget.store,
				selectionModel : function() { return widget.grid.getSelectionModel(); },
				hooks          : Ext.value(config.selection.hooks, {}),
				useSelection   : Ext.value(config.selection.useSelection, true),
				useCheckboxes  : Ext.value(config.selection.useCheckboxes, true),
				statusbar      : config.selection.statusbar
				
			};
			
			widget.selection = panel.widgets.selection(widget.selection);
			
			widget.observer.on("init", function() {
			
				widget.selection.init();
				
				var _fe = function() { widget.selection.clearSelections(); };
				
				widget.observer.on("before_reload",       _fe);
				widget.observer.on("reload",              _fe);
				widget.observer.on("before_items_add",    _fe);
				widget.search.widget.on("onBeforeSearch", _fe);
				widget.search.widget.on("onAfterClear",   _fe);
				
				delete _fe;
				
				var _fe = function() { 
				
					widget.selection.checkStatus(); 
					widget.selection.observer.fireEvent("selection");
					
				};
				
				widget.observer.on("reload",          _fe);
				widget.observer.on("items_added",     _fe);
				widget.observer.on("items_removed",   _fe);
				
				delete _fe;
				
			});
			
		}	// if
		
		/**
		 * Search:
		**/
		widget.search = {
			
			hidden:    Ext.value(config.search.hidden, false),
			mode:      Ext.value(config.search.mode, "local"),
			width:     Ext.value(config.search.width, 270),
			menuStyle: Ext.value(config.search.menuStyle, (config.search.mode == "remote" ? "radio" : "checkbox")),
			minChars:  Ext.value(config.search.minChars, undefined),
			highlightSeparator: Ext.value(config.search.highlightSeparator, undefined),
			highlight: function() { return widget.grid.getView().mainBody.dom },
			disableMenu: Ext.value(config.search.disableMenu, false),
			
			toolbarContainer: Ext.value(config.search.toolbarContainer, undefined),
			
			checkIndexes: [
			],
			
			disableIndexes: [
				"is_active",
				"is_filtered",
				"is_checked",
				"is_new",
				"is_modified",
				"is_leaf",
				"parent",
				"parents"
			]
			
		};
		
		Ext.value(config.search.checkIndexes, []).each( function(i) {
			
			widget.search.checkIndexes.push(i);
			
		});
		
		Ext.value(config.search.disableIndexes, []).each( function(i) {
			
			widget.search.disableIndexes.push(i);
			
		});
				
		if( config.positioner ) {
			widget.search.disableIndexes.push( Ext.value(config.positioner.dataIndex, "position") ); }
			
		widget.search = panel.widgets.chunks.grid.search(widget.search);			
			
		/**
		 * TreeGrid specific actions 
		**/
		if( config.hierarchy && config.search.mode == "remote" ) {
			
			widget.search.widget.on("onAfterClear", function(sobj, val, store) {
					
				widget.store.baseParams  = [];
				widget.store.lastOptions = [];
				widget.store.active_node = null;
				widget.store.reload();
				
			});
				
			widget.search.widget.on("onBeforeSearch", function(sobj, val, store) {
					
				widget.store.baseParams  = [];
				widget.store.lastOptions = [];
				widget.store.active_node = null;
				widget.store.removeAll();
				
			});
				
			widget.search.widget.on("onSearch", function(me, search, store) {
					
				widget.grid.expandAllNodes();
										
			});
			
		}	// if
		
		/**
		 * Clear search mode when adding new items:
		**/
		var _fe = function() {
			
			if( widget.search.widget.isSearchApplied() ) {
			
				if( config.search.autoApply ) {
					
					widget.search.widget.onTriggerSearch();
					
				} else {
				
					widget.search.widget.onTriggerClear();
					
				}	// if
				
			}	// if
			
		};
		
		widget.observer.on("before_items_add", _fe);
		widget.observer.on("reload", _fe);
		
		delete _fe;
		
		/**
		 * Positioner:
		**/
		if( config.positioner ) {
		
			widget.observer.addEvents({
				
				"items_moved": true
				
			});
			
			config.positioner.dataIndex  = Ext.value(config.positioner.dataIndex, "position");
			config.positioner.store      = Ext.value(config.positioner.store,     widget.store);
			config.positioner.grid       = Ext.value(config.positioner.grid,      function() { return widget.grid; });
			config.positioner.selection  = Ext.value(config.positioner.selection, widget.selection);
		
			widget.positioner = new panel.widgets.positioner(config.positioner);
			
			widget.positioner.observer.on("before_move", function() {
				
				// PERFORMANCE
				widget.store.suspendEvents();
				widget.selection.observer.suspendEvents();
				
			});
		
			widget.positioner.observer.on("move", function(records) {
				
				records.each( function(record) {
					
					record.data.is_modified = true;
					
				});		

				// PERFORMANCE
				widget.store.resumeEvents();
				widget.selection.observer.resumeEvents();
				
				widget.store.fireEvent("datachanged");
				widget.ensureVisible( records[0] );
				
				widget.observer.fireEvent("items_moved", records);
				
			});
		
			/**
			 * Refresh positioner on config_list change 
			**/
			var _fe = function() {
				
				widget.positioner.refresh();
				
			};
			
			widget.observer.on("items_added",   _fe);	
			widget.observer.on("items_removed", _fe);
			widget.observer.on("init",          widget.positioner.init);
		
			delete _fe;
			
		}	// if
		
		/**
		 * Filters:
		**/
		if( config.filters ) {
		
			widget.filters = new Ext.ux.grid.GridFilters({
				
				autoReload: false,
				local: true,
				
				filters: Ext.value(config.filters.fields, [])
				
			});
			
		}	// if
		
		/**
		 * Grid:
		**/
		
		widget.grid = {};
		
		/**
		 * Grid BARS
		**/

		config.grid.tbar = Ext.value(config.grid.tbar, {});
		config.grid.bbar = Ext.value(config.grid.bbar, {});
		
		if( config.selection && config.selection.statusbar ) {
			
			(function() {
			
				var items = Ext.value(config.grid.bbar[1], []);
			
				config.grid.bbar[ 1 ] = ( widget.selection.statusbar.bar ); 
			
				widget.selection.observer.on("init", function() {
				
					items.each( function(item) {
						
						widget.selection.statusbar.bar.add(item);
						
					});
				
				});
				
			}());
			
		}
					
		if( config.positioner ) {
			
			config.positioner.tbar = Ext.value(config.positioner.tbar, 1);
			
			config.grid.tbar[config.positioner.tbar] = Ext.value(config.grid.tbar[config.positioner.tbar], []);
			
			if( Ext.value(config.positioner.tbar_align, "left") ) {
			
				config.grid.tbar[config.positioner.tbar].unshift(
					widget.positioner.buttons.move_up,
					widget.positioner.buttons.move_down,
					"-",
					widget.positioner.buttons.move_to_up,
					widget.positioner.buttons.move_to_down
				);
				
			} else {
				
				config.grid.tbar[config.positioner.tbar].push(
					widget.positioner.buttons.move_up,
					widget.positioner.buttons.move_down,
					"-",
					widget.positioner.buttons.move_to_up,
					widget.positioner.buttons.move_to_down
				);
				
			}
						
		}	// if
		
		if( config.search && (config.search.toolbarContainer == undefined) ) {
			
			if( config.grid.tbar[1] ) {
			
				config.grid.tbar[1].push("->");
				
			} else {
				
				config.grid.tbar[1] = ["->"];
				
			}	// if
			
		}	// if
		
		if( config.paginator ) {
			
			widget.grid.paginator = new Ext.PagingToolbar({
				
		        pageSize    : Ext.value(config.paginator.pageSize, 25),
		        store       : widget.store,
		        displayInfo : true,
		        displayMsg  : "Displaying records {0} - {1} of {2}",
		        emptyMsg    : "No records to display"
				
		    });
			
			config.grid.bbar[ $H(config.grid.bbar).getLength() + 1 ] = widget.grid.paginator;
			
		}	// if
			
		/**
		 * Grid Columns: 
		**/
		widget.grid.columns = [];
		widget.grid.plugins = [];
		
		if( config.selection && config.selection.useCheckboxes ) {
			
			widget.grid.columns.push( widget.selection.check_model.column );
			
		};	// if
		
		if( config.positioner ) {
			
			widget.grid.columns.push(widget.positioner.column);
			 
		};	// if
		
		config.grid.internal_columns = Ext.value(config.grid.internal_columns, {});
		
		(function() {
			
			var column = Ext.value(config.grid.internal_columns.uid, {
				dataIndex: "uid",
				header: "UID",
				hidden: true
			});
			
			if( column ) {
				widget.grid.columns.push(column); }
			
		}());
						
		config.grid.columns.each( function(column) {
			
			widget.grid.columns.push(column);
			
			switch( true ) {
			
			case ( column instanceof Ext.grid.CheckboxColumn ):
			case ( column instanceof Ext.grid.RowExpander ):
				widget.grid.plugins.push(column);
				break;
				
			}
			
		});
			
		/**
		 * Grid Panel
		**/
		if( config.search ) {
			
			widget.grid.plugins.push( widget.search.widget );
			
		}	// if
		
		if( config.filters ) {
			
			widget.grid.plugins.push(widget.filters);
			
		}	// if
		
		if( config.selection && config.selection.useCheckboxes ) {
			
			widget.grid.plugins.push( widget.selection.check_model.column );
			
		}	// if

		widget.grid = {
			
			id               : Ext.value(config.grid.id, config.id),
			iconCls          : Ext.value(config.grid.iconCls, undefined),
			title            : Ext.value(config.grid.title, undefined),
			width            : Ext.value(config.grid.width, undefined),
			region           : Ext.value(config.grid.region, "center"),
			collapsible      : Ext.value(config.grid.collapsible, false),
			split            : Ext.value(config.grid.split, false),
			height           : Ext.value(config.grid.height, undefined),
			autoHeight       : Ext.value(config.grid.autoHeight, undefined),
			margins          : Ext.value(config.grid.margins, "1 1 1 1"),
			border           : Ext.value(config.grid.border, true),
			cls              : Ext.value(config.grid.cls, undefined),
			baseCls          : Ext.value(config.grid.baseCls, undefined),
			frame            : Ext.value(config.grid.frame, undefined),
			disableSelection : Ext.value(config.grid.disableSelection, false),
			autoScroll       : true,
			stripeRows       : Ext.value(config.grid.stripeRows, true),
			enableDragDrop   : (config.positioner ? true : false),
			renderTo         : Ext.value(config.grid.renderTo, undefined),
			autoWidth        : true,
			draggable        : false,
			forceLayout      : true,
			autoExpandColumn : Ext.value(config.grid.autoExpandColumn, undefined),
			clicksToEdit     : 1,
			loadMask         : true,
			trackMouseOver   : false,
			enableHdMenu     : Ext.value(config.grid.enableHdMenu, true),
			enableColumnHide : Ext.value(config.grid.enableColumnHide, true),
			enableColumnMove : Ext.value(config.grid.enableColumnMove, true),
			enableColumnResize : Ext.value(config.grid.enableColumnResize, true),
			monitorResize: true,
			stateful: Ext.value(config.grid.stateful, false),
			
			listeners : Ext.value(config.grid.listeners, undefined),
			store     : widget.store,
			plugins   : widget.grid.plugins,
			
			tools: Ext.value(config.grid.tools, []),
			
			tbar: Ext.value( 
				config.grid.tbar[1],
				undefined
			),
			
			bbar: Ext.value( 
				config.grid.bbar[1],
				undefined
			),
			
			columns: widget.grid.columns,
			
			sm: (
				!Ext.value(config.grid.disableSelection, false) ? 
					new Ext.grid.RowSelectionModel({ singleSelect: true }) :
					undefined
			)
			
		};
		
		/**
		 * Fix for baseCls undefined
		 */
		if( widget.grid.baseCls == undefined ) {
			delete widget.grid.baseCls; }
		
		/**
		 * ViewConfig
		**/
		
		config.grid.viewConfig  = Ext.value(config.grid.viewConfig, {});

		config.grid.viewConfig.deferEmptyText = Ext.value(
			config.grid.viewConfig.deferEmptyText, 
			false
		);
		
		config.grid.viewConfig.emptyText = Ext.value(
			
			config.grid.viewConfig.emptyText, 
			function() { 
			
				return panel.widgets.chunks.grid.view.emptyText( function() {
				
					if( widget.search.widget.isSearchApplied() ) {
						
						return "Search have no results";
						
					} else {
						
						return config.texts.list_is_empty;
						
					}	// if
					
				});
			
			}
			
		);
		
		if( config.hierarchy ) {
			
			config.grid.viewConfig.useArrows     = Ext.value(config.grid.viewConfig.useArrows, true);
			config.grid.viewConfig.noElbowOnLeaf = Ext.value(config.grid.viewConfig.noElbowOnLeaf, false);
			
		};
		
		widget.grid.viewConfig = config.grid.viewConfig;
		
		if( config.hierarchy ) {
			
			widget.grid.root_title               = "*";
			widget.grid.master_column_id         = config.grid.master_column_id;
			widget.grid.autoExpandColumn         = Ext.value(config.grid.autoExpandColumn, undefined);
			
			var _ec = panel.widgets.chunks.panel.tools.GridExpandCollapse({
			
				grid: function() { return widget.grid; }
				
			});
			
			widget.grid.tools.push(
				_ec.toolCollapse,
				_ec.toolExpand
			);
			
		}	// if
		
		
		switch( true ) {
			
		case config.hierarchy && config.grid.editable:
		case config.hierarchy:
			widget.grid = new Ext.ux.maximgb.treegrid.GridPanel(widget.grid);
			break;
			
		case config.grid.editable:
			widget.grid = new Ext.grid.EditorGridPanel(widget.grid);
			break;
			
		default:
			widget.grid = new Ext.grid.GridPanel(widget.grid);
			break;
			
		}	// switch
		
		widget.panel = widget.grid;
		
		if( config.grid.title_css ) {
			
			widget.observer.on("init", function() {
				
				widget.grid.header.addClass( config.grid.title_css );
				
			});
			
		}	// if
		
		widget.grid.on("render", function() {
			
			widget.locker.setElement( widget.grid.getEl() );
			
		});
		
		/**
		 * Render TBARS 
		**/
		
		widget.grid.on("render", function() {
	
			widget.grid.tbars = {
				
				1: widget.grid.tbar
				
			};
			
			$H(config.grid.tbar).each( function( tbar, key ) {
				
				if( key == 1 ) { return; }

				if( Ext.type(tbar) == "array" ) {
					
					 if( Ext.value(config.grid.tbarFit[key], true) === true ) {
					
						widget.grid.tbars[key] = new Ext.FitToolbar({
						
							renderTo: widget.grid.tbars[key-1],
							items:    tbar
							
						});
						
					} else {
						
						widget.grid.tbars[key] = new Ext.Toolbar({
						
							renderTo: widget.grid.tbars[key-1],
							items:    tbar
							
						});
						
					}
					
				} else {
					
					tbar.rendered = false;
					tbar.render(widget.grid.tbars[key-1]);
					widget.grid.tbars[key] = tbar;
										
				}	// if			
				
			});
			
		});
		
		/**
		 * Render BBARS 
		**/
		
		widget.grid.on("render", function() {
	
			widget.grid.bbars = {
				
				1: widget.grid.bbar
				
			};
			
			$H(config.grid.bbar).each( function( bbar, key ) {
				
				if( key == 1 ) { return; }

				if( Ext.type(bbar) == "array" ) {
					
					 if( Ext.value(config.grid.bbarFit[key], true) === true ) {
					
						widget.grid.bbars[key] = new Ext.FitToolbar({
						
							renderTo: widget.grid.bbars[key-1],
							items:    bbar
							
						});
						
					} else {
						
						widget.grid.bbars[key] = new Ext.Toolbar({
						
							renderTo: widget.grid.bbars[key-1],
							items:    bbar
							
						});
						
					}
					
				} else {
					
					bbar.rendered = false;
					bbar.render(widget.grid.bbars[key-1]);
					widget.grid.bbars[key] = bbar;
										
				}	// if			
				
			});
			
		});
		
		widget.observer.on("destroy", function() {
			
			widget.grid.destroy();
			widget.grid = undefined;
			
			widget.panel.destroy();
			widget.panel = undefined;
			
		});
		
		widget.enable = function() {
			
			widget.grid.enable();
			
		};
		
		widget.disable = function() {
			
			widget.grid.disable();
			
		};
		
		/**
		 * Return:
		**/
		
		return widget;
		
	};
